#!/usr/bin/perl
use strict;
use XML::Parser;

my $INPUT_XML;

my $CODE = "Code";
my $LAT = "Lat";
my $LINECODE1 = "LineCode1";
my $LINECODE2 = "LineCode2";
my $LINECODE3 = "LineCode3";
my $LINECODE4 = "LineCode4";
my $LON = "Lon";
my $NAME = "Name";
my $STATIONTOGETHER1 = "StationTogether1";
my $STATIONTOGETHER2 = "StationTogether2";
my $STATION = "Station";
my $STATIONS = "Stations";
my $STATIONSRESP = "StationsResp";


my $current_element_id = "";
my $buf = "";
my %station = ();

my %lineMap = (
"BL" => "BLUE",
"GR" => "GREEN",
"OR" => "ORANGE",
"RD" => "RED",
"YL" => "YELLOW",
"SV" => "SILVER",
);

my %stations = ();

my $in_Station = 0;


#-----------------------------------------------------------------%%%
# usage - 
#--------------------------------------------------------------------
sub usage{
    my $usage = "Usage:\n\t" ;
    $usage .= "perl $0  input_xml\n";
    return $usage;
}

#-----------------------------------------------------------------%%%
# parse params
#--------------------------------------------------------------------
sub parseParams{
    my $rval = 0;
    
    my $argc = scalar(@ARGV);
    if (0 < $argc ) {
	$INPUT_XML = $ARGV[0];
    } else {
	print &usage();
	$rval = -1;
    }
    
    return $rval;
}

#-----------------------------------------------------------------%%%
sub loadCsv {
  open(CSV,"<stations.csv") || die "Could not open csv\n";

  while(<CSV>) {
        chomp(my $str = $_);

        if($. == 1) { next; }

        my ($apiCode,$apiAltCode,$const,$webName,$webCode,$endOfLine,$line1,$line2,$line3,$line4) = split(/,/, $str);
	my %station = (
	"apiCode" => $apiCode,
	"apiAltCode" => $apiAltCode,
	"const" => $const,
	"webName" => $webName,
	"webCode" => $webCode,
	"endOfLine" => $endOfLine,
	"lines" => ""
	);

	$stations{$apiCode} = \%station;
#print "CSV: |$apiCode|\n";
  }
 


  close(CSV);
}
#-----------------------------------------------------------------%%%
sub start_handler {
    my $p = shift;
    my $el = shift;
    my %attributes = @_;

    if($in_Station == 1) {
      if (($el eq $CODE ) ||
          ($el eq $LAT ) ||
          ($el eq $LINECODE1 ) ||
          ($el eq $LINECODE2 ) ||
          ($el eq $LINECODE3 ) ||
          ($el eq $LINECODE4 ) ||
          ($el eq $LON ) ||
          ($el eq $NAME ) ||
          ($el eq $STATIONTOGETHER1 ) ||
          ($el eq $STATIONTOGETHER2 ) ) {

          $current_element_id = $el;
           $buf = "";
      }
    } elsif ($el eq $STATION ) {
        $current_element_id = $STATION;
        $in_Station = 1;
        %station = ();
        $station{$CODE } = "";
        $station{$LAT } = "";
        $station{$LINECODE1 } = "";
        $station{$LINECODE2 } = "";
        $station{$LINECODE3 } = "";
        $station{$LINECODE4 } = "";
        $station{$LON } = "";
        $station{$NAME } = "";
        $station{$STATIONTOGETHER1 } = "";
        $station{$STATIONTOGETHER2 } = "";
    }

} #start_handler


#-----------------------------------------------------------------%%%
# char_handler - handler for character data.  We only care about 
#  \\SearchGroup\Name element data
#--------------------------------------------------------------------
sub char_handler {
#	print "char:" . join ("\t", @_) . "\n";
	my ($Expat, $el) = @_;
        chomp(my $str = $el);

        if($in_Station == 1) {
	   $str =~ s/^\s+//;
	   $str =~ s/\s+$//;
		$buf .= $str;
        }
} # End of char_handler

sub default_handler {
  # Do Nothing
} 
sub end_handler {
#	print "end:" . join ("\t", @_) . "\n";
	my ($expat, $el) = @_;

  if ($el eq $STATION ) {
    $current_element_id = "";
    $in_Station = 0;

    my $apiCode = $station{$CODE};
    my $apiAltCode = $station{$STATIONTOGETHER1};

      #print $msg . "\n";
    my $s_ref;

    if(exists $stations{$apiCode}) {
      $s_ref = $stations{$apiCode};
    } elsif(exists $stations{$apiAltCode }) {
      $s_ref = $stations{$apiAltCode};
    } else {
      print "Dont know station " . $station{$NAME} . " with code " . $station{$CODE} . "\n";
      return; 
    }

    my @lines = ( $station{$LINECODE1 } || "", 
                    $station{$LINECODE2 } || "", 
                    $station{$LINECODE3 } || "",
                    $station{$LINECODE4 } || ""
               );
    $$s_ref{"lines"} = $$s_ref{"lines"} . join(",", @lines);
    $$s_ref{"lat"} = $station{$LAT};
    $$s_ref{"lon"} = $station{$LON};
    # Station data is swapped in DB.
    #//o>     WEST_FALLS_CHURCH_VT_UVA("E07", "West Hyattsville", 38.9550401707, -76.9695766751 ,GREEN),
    #//>     WEST_HYATTSVILLE("K06", "W Falls Church", 38.900780551, -77.1890948225 ,ORANGE),

    if("E07" eq $$s_ref{"apiCode"}) {
      $$s_ref{"webName"} = "W Falls Church";
    } elsif("K06" eq $$s_ref{"apiCode"}) {
      $$s_ref{"webName"} = "West Hyattsville";
    } else {
      $$s_ref{"webName"} = $station{$NAME};
    }

  } elsif($in_Station == 1) {
      if (($el eq $CODE ) ||
          ($el eq $LAT ) ||
          ($el eq $LINECODE1 ) ||
          ($el eq $LINECODE2 ) ||
          ($el eq $LINECODE3 ) ||
          ($el eq $LINECODE4 ) ||
          ($el eq $LON ) ||
          ($el eq $NAME ) ||
          ($el eq $STATIONTOGETHER1 ) ||
          ($el eq $STATIONTOGETHER2 ) ) {
      $current_element_id = $el;
      $station{$el} = $buf;
    }
  }

} #end_handler


sub printJava {

print <<EOF;
package app.transittool.model;

import static app.transittool.util.Constants.BLUE;
import static app.transittool.util.Constants.GREEN;
import static app.transittool.util.Constants.ORANGE;
import static app.transittool.util.Constants.RED;
import static app.transittool.util.Constants.SILVER;
import static app.transittool.util.Constants.YELLOW;

public enum TrainStation {
EOF

my @lines = (); 
foreach my $apiCode (sort keys %stations) {
	  my $s_ref = $stations{$apiCode};

    my $apiCode = $$s_ref{"apiCode"};
    my $apiAltCode = $$s_ref{"apiAltCode"};
    my $const = $$s_ref{"const"};
    my $webName = $$s_ref{"webName"};
    my $webCode = $$s_ref{"webCode"};
    my $lat = $$s_ref{"lat"};
    my $lon = $$s_ref{"lon"};
    my $endOfLine = $$s_ref{"endOfLine"};
    my $lines = $$s_ref{"lines"};


    my $lineStr = "";
    foreach my $line (sort split(/,/, $lines)) {
      if(exists $lineMap{$line}) {
        $lineStr .= "," . $lineMap{$line};
      }
    }


    if($apiAltCode ne "") {
      push(@lines, "    $const(\"$apiCode\", \"$apiAltCode\", \"$webName\", $lat, $lon " . "$lineStr),");
    } else {
      push(@lines, "    $const(\"$apiCode\", \"$webName\", $lat, $lon " . "$lineStr),");
    }

}

print join("\n",sort @lines);
print "\n\n";

print <<EOF;
 UNKNOWN("UNKNOWN", null, "UNKNOWN", -1, -1, TrainLine.UNKNOWN);
    ;

} 

EOF

  }

#-----------------------------------------------------------------%%%
# main
#--------------------------------------------------------------------
sub main(){
	if( 0 > &parseParams() ) {
		exit(-1);
	} 

	die "Can't find file \"$INPUT_XML\""  unless -f $INPUT_XML;
    
	#&clear_state();

	loadCsv();
	
	my $parser = new XML::Parser(ErrorContext => 2);
	
	$parser->setHandlers(Start => \&start_handler,
						 End   => \&end_handler,
						 Char => \&char_handler,
						 Default => \&default_handler);
	$parser->parsefile($INPUT_XML);

	printJava();

}
#-----------------------------------------------------------------%%%
# live action
#--------------------------------------------------------------------
&main();
1;
__END__



wget http://api.wmata.com/Rail.svc/Stations?api_key=XXX
perl stationXmlToCsv.pl ../Stations.xml
